package cn.sunshine;

import lombok.SneakyThrows;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

/**
 * @Description 自定义文件类加载器  jvm 类加载器: appLoader -> extLoader -> bootstrap
 * @Author Mokairui
 * @Since 2021/12/4
 */
public class MyFileClassLoader extends ClassLoader {
    private String direction;

    public MyFileClassLoader(String direction) { // 不指定父类加载器, 默认则为 AppLoader
        this.direction = direction;
    }

    public MyFileClassLoader(ClassLoader parent, String direction) { // 又自己指定类加载器
        super(parent);
        this.direction = direction;
    }

    // name: cn.sunshine.demo
    @SneakyThrows
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // 把类名转换为目录
        String file = direction + File.separator + name.replace(".", File.separator) + ".class"; // name -> D://cn/sunshine/demo
        // 构建输入流
        try (InputStream in = new FileInputStream(file);
             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            byte[] buf = new byte[1024];
            int len = -1;
            while ((len = in.read()) != -1) {
                baos.write(buf);
            }
            byte data[] = baos.toByteArray(); // 读取到的字节码的二进制数据
            return defineClass(name, data, 0, data.length);
        }
    }

    public static void main(String[] args) throws Exception {
        MyFileClassLoader classLoader = new MyFileClassLoader("d:/");
        Class<?> clazz = classLoader.loadClass("cn.sunshine.demo");
        clazz.getDeclaredConstructor().newInstance();
    }
}
